
from PIL import Image
# import sys
from prettytable import PrettyTable
from sklearn import svm
from sklearn.cluster import DBSCAN
from sklearn.ensemble import IsolationForest
from sklearn.neighbors import LocalOutlierFactor
from streamlit_extras.colored_header import colored_header
from streamlit_option_menu import option_menu

from business.algorithm.utils import *



def run():

    with st.sidebar:
        sub_option = option_menu(None, ["数据可视化", "异常值检测", "数据库"])
    if sub_option == "数据库":
        colored_header(label="数据库", description=" ", color_name="violet-90")
        col1, col2 = st.columns([2, 2])
        with col1:
            df = pd.read_csv('./data/Case 1.csv')
            st.write("多晶陶瓷")
            image = Image.open('./data/fig4.png')
            st.image(image, width=280, caption='')
            tmp_download_link = download_button(df, f'data.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)
        with col2:
            df = pd.read_csv('./data/Case 3_R.csv')
            st.write("FGH98高温合金")
            image = Image.open('./data/fig6.png')
            st.image(image, width=280, caption='')
            tmp_download_link = download_button(df, f'data.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

        col1, col2 = st.columns([2, 2])
        with col1:
            df = pd.read_csv('./data/HEA-Dataset.csv')
            st.write("高熵合金")
            image = Image.open('./data/fig3.png')
            st.image(image, width=280, caption='')
            tmp_download_link = download_button(df, f'data.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

        with col2:
            df = pd.read_csv('./data/Case 1_R.csv')
            st.write("低合金钢")
            image = Image.open('./data/fig1.png')
            st.image(image, width=280, caption='')
            tmp_download_link = download_button(df, f'data.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

        col1, col2 = st.columns([2, 2])
        with col1:
            df = pd.read_csv('./data/RAFM-dataset.csv')
            st.write("铁素体马氏体钢")
            image = Image.open('./data/fig5.png')
            st.image(image, width=280, caption='')
            tmp_download_link = download_button(df, f'data.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)
        with col2:
            df = pd.read_csv('./data/Case 2.csv')
            st.write("非晶态合金")
            image = Image.open('./data/fig2.png')
            st.image(image, width=280, caption='')
            tmp_download_link = download_button(df, f'data.csv', button_text='download')
            st.markdown(tmp_download_link, unsafe_allow_html=True)

    elif sub_option == "数据可视化":

        colored_header(label="数据可视化", description=" ", color_name="violet-90")
        file = st.file_uploader("Upload `.csv` file", type=['csv'], label_visibility="collapsed")
        if file is None:
            table = PrettyTable(['file name', 'class', 'description'])
            table.add_row(['file_1', 'dataset', 'data file'])
            st.write(table)
        if file is not None:
            df = pd.read_csv(file)
            check_string_NaN(df)

            colored_header(label="数据信息", description=" ", color_name="violet-70")

            nrow = st.slider("行数", 1, len(df), 5)
            df_nrow = df.head(nrow)
            st.write(df_nrow)

            colored_header(label="数据统计", description=" ", color_name="violet-30")

            st.write(df.describe())

            tmp_download_link = download_button(df.describe(), f'statistics.csv', button_text='download')

            st.markdown(tmp_download_link, unsafe_allow_html=True)

            colored_header(label="特征&目标", description=" ", color_name="violet-70")

            target_num = st.number_input('目标数量', min_value=1, max_value=10, value=1)
            col_feature, col_target = st.columns(2)
            # features
            features = df.iloc[:, :-target_num]
            # targets
            targets = df.iloc[:, -target_num:]
            with col_feature:
                st.write(features.head())
            with col_target:
                st.write(targets.head())

            colored_header(label="特征分布", description=" ", color_name="violet-30")
            feature_selected_name = st.selectbox('特征', list(features), 1)
            feature_selected_value = features[feature_selected_name]
            plot = customPlot()
            col1, col2 = st.columns([1, 3])
            with col1:
                with st.expander("绘图参数"):
                    options_selected = [plot.set_title_fontsize(18), plot.set_label_fontsize(19),
                                        plot.set_tick_fontsize(20), plot.set_legend_fontsize(21),
                                        plot.set_color('柱颜色', 0, 22)]
            with col2:
                plot.feature_distribution(options_selected, feature_selected_name, feature_selected_value)

            with col1:
                with st.expander("绘图参数"):
                    options_selected = [plot.set_title_fontsize(1), plot.set_label_fontsize(2),
                                        plot.set_tick_fontsize(3), plot.set_legend_fontsize(4),
                                        plot.set_color('line color', 6, 5), plot.set_color('柱颜色', 0, 6)]
            with col2:
                plot.feature_hist_kde(options_selected, feature_selected_name, feature_selected_value)

            # =========== Targets visulization ==================

            colored_header(label="目标分布", description=" ", color_name="violet-30")

            target_selected_name = st.selectbox('target', list(targets))

            target_selected_value = targets[target_selected_name]
            plot = customPlot()
            col1, col2 = st.columns([1, 3])
            with col1:
                with st.expander("绘图参数"):
                    options_selected = [plot.set_title_fontsize(7), plot.set_label_fontsize(8),
                                        plot.set_tick_fontsize(9), plot.set_legend_fontsize(10),
                                        plot.set_color('line color', 6, 11), plot.set_color('柱颜色', 0, 12)]
            with col2:
                plot.target_hist_kde(options_selected, target_selected_name, target_selected_value)

            # =========== Features analysis ==================

            colored_header(label="特征分析", description=" ", color_name="violet-30")

            feature_range_selected_name = st.slider('特征数量', 1, len(features.columns), (1, 2))
            min_feature_selected = feature_range_selected_name[0] - 1
            max_feature_selected = feature_range_selected_name[1]
            feature_range_selected_value = features.iloc[:, min_feature_selected: max_feature_selected]
            data_by_feature_type = df.groupby(list(feature_range_selected_value))
            feature_type_data = create_data_with_group_and_counts(data_by_feature_type)
            IDs = [str(id_) for id_ in feature_type_data['ID']]
            Counts = feature_type_data['Count']
            col1, col2 = st.columns([1, 3])
            with col1:
                with st.expander("绘图参数"):
                    options_selected = [plot.set_title_fontsize(13), plot.set_label_fontsize(14),
                                        plot.set_tick_fontsize(15), plot.set_legend_fontsize(16),
                                        plot.set_color('柱颜色', 0, 17)]
            with col2:
                plot.featureSets_statistics_hist(options_selected, IDs, Counts)
        st.write('---')

    elif sub_option == "异常值检测":
        colored_header(label="异常值检测", description=" ", color_name="violet-90")
        file = st.file_uploader("Upload `.csv` file", type=['csv'], label_visibility="collapsed")
        if file is None:
            table = PrettyTable(['file name', 'class', 'description'])
            table.add_row(['file_1', 'dataset', 'data file'])
            st.write(table)
        if file is not None:
            df = pd.read_csv(file)
            check_string_NaN(df)
            colored_header(label="数据信息", description=" ", color_name="violet-70")
            nrow = st.slider("rows", 1, len(df), 5)
            df_nrow = df.head(nrow)
            st.write(df_nrow)

            colored_header(label="特征&目标", description=" ", color_name="violet-70")

            target_num = st.number_input('目标数量', min_value=1, max_value=10, value=1)

            col_feature, col_target = st.columns(2)

            features = df.iloc[:, :-target_num]

            targets = df.iloc[:, -target_num:]
            with col_feature:
                st.write(features.head())
            with col_target:
                st.write(targets.head())

            # colored_header(label="target", description=" ", color_name="violet-70")

            # target_selected_option = st.selectbox('target', list(targets)[::-1])

            # target = targets[target_selected_option]

            colored_header(label="异常值检测", description=" ", color_name="violet-30")

            model_path = './models/outlier detection'

            template_alg = model_platform(model_path)

            inputs, col2 = template_alg.show()

            if inputs['model'] == 'One Class SVM':
            
                detector = svm.OneClassSVM(nu=inputs['nu'], kernel='rbf', gamma=inputs['gamma'])
                detector.fit(features)
                outlier = detector.predict(features)
                normal = df[outlier == 1]
                abnormal = df[outlier == -1]
                st.write('------------------ 正常 --------------------')
                st.write(normal)
                tmp_download_link = download_button(normal, f'normal.csv', button_text='download')
                st.markdown(tmp_download_link, unsafe_allow_html=True)

                st.write('------------------ 异常 --------------------')
                st.write(abnormal)
                tmp_download_link = download_button(abnormal, f'abnormal.csv', button_text='download')
                st.markdown(tmp_download_link, unsafe_allow_html=True)

            elif inputs['model'] == 'IsolationForest':

                detector = IsolationForest(n_estimators=inputs['n_estimators'], contamination=inputs['contamination'],
                                           random_state=inputs['random state'])
                detector.fit(features)
                outlier = detector.predict(features)

                normal = df[outlier == 1]
                abnormal = df[outlier == -1]
                st.write('------------------ 正常 --------------------')
                st.write(normal)
                tmp_download_link = download_button(normal, f'normal.csv', button_text='download')
                st.markdown(tmp_download_link, unsafe_allow_html=True)

                st.write('------------------ 异常 --------------------')
                st.write(abnormal)
                tmp_download_link = download_button(abnormal, f'abnormal.csv', button_text='download')
                st.markdown(tmp_download_link, unsafe_allow_html=True)

            elif inputs['model'] == 'DBSCAN':

                model = DBSCAN()
                model.fit(features)
                outlier = model.labels_
                normal = df[outlier == 1]
                abnormal = df[outlier == -1]
                st.write('------------------ 正常 --------------------')

                st.write(normal)
                tmp_download_link = download_button(normal, f'normal.csv', button_text='download')
                st.markdown(tmp_download_link, unsafe_allow_html=True)

                st.write('------------------ 异常 --------------------')
                st.write(abnormal)
                tmp_download_link = download_button(abnormal, f'abnormal.csv', button_text='download')
                st.markdown(tmp_download_link, unsafe_allow_html=True)

            elif inputs['model'] == 'LocalOutlierFactor':

                detector = LocalOutlierFactor(n_neighbors=20, contamination=0.1)
                outlier = detector.fit_predict(features)

                normal = df[outlier == 1]
                abnormal = df[outlier == -1]
                st.write('------------------ 正常 --------------------')
                st.write(normal)
                tmp_download_link = download_button(normal, f'normal.csv', button_text='download')
                st.markdown(tmp_download_link, unsafe_allow_html=True)

                st.write('------------------ 异常 --------------------')
                st.write(abnormal)
                tmp_download_link = download_button(abnormal, f'abnormal.csv', button_text='download')
                st.markdown(tmp_download_link, unsafe_allow_html=True)
